home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Orlando_1993 / Devcon93.4 / CAMD / docs / realtime.readme < prev   
Encoding:
Text File  |  1993-01-11  |  18.1 KB  |  361 lines

  1. =========================================================================
  2.                              RealTime.library
  3. =========================================================================
  4.  
  5. Introduction
  6. ~~~~~~~~~~~~
  7.     RealTime library is a shared library for the Amiga, designed to help
  8. applications synchronize to one another. An example of this is an animation
  9. player which could synchronize to a music program; Or, both of them could
  10. be sync'd to an external source such as SMPTE time code.
  11.     RealTime allows any number of timing contexts, or "conductors", so
  12. called because of their similarity to the conductor of an orchestra.
  13. RealTime's function is essentially to function as a metronome or master
  14. clock, distributing a continuous stream of timing information to different
  15. tasks.
  16.  
  17. Goals
  18. ~~~~~
  19.     The goals of RealTime are:
  20.  
  21.     1. To encourage development of music software and synchronized
  22. multimedia applications by providing a working driver to the public.
  23.  
  24.     2. To spur the development of applications which allow the user to
  25. create and control multimedia presentations.
  26.  
  27. Operating System Requirements
  28. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  29.     The RealTime library functions identically under 2.0 or 1.3. However,
  30. many of the various utilities that come with RealTime require GadTools or
  31. other 2.0 features.
  32.  
  33. The Conductor System
  34. ~~~~~~~~~~~~~~~~~~~~
  35.     RealTime maintains a list of conductors and sends timing information to
  36. individual "players" (like the musicians in an orchestra). There can be any
  37. number of conductors, and each represents a seperate timing context, just
  38. like real musicians playing in different concert halls don't have to stay
  39. in time with each other. Similarly, there can be any number of players.
  40.     An application will usually create a single PlayerInfo structure
  41. (using the CreatePlayer() call) and the attach it to a conductor. (If the
  42. conductor does not yet exist, it will automatically be created). In some
  43. cases, an application might want to create more than one player, when
  44. multiple independent timing contexts are required.
  45.     The conductors are driven by a central clock in RealTime called the
  46. "heartbeat", which is driven by the Amiga's timer chips at a rate of 600
  47. ticks per second. The heartbeat clock pulses are then distributed to the
  48. conductors, which are then distributed to the various players. (Historical
  49. note: The RealTime Heartbeat was originally 500 Hz (2 ms per tick),
  50. however a number of people requested that the tick rate be an even
  51. multiple of the NTSC, PAL and motion picture frame rates (30, 25 and 24
  52. Hz, respectively)).
  53.     Each conductor keeps track of the variables that pertain to a
  54. particular timing context. These include:
  55.  
  56.     -- the state of the conductor, i.e. running, stopped, paused,
  57.         locating, etc.
  58.     -- what time it is, relative to some agreed-upon "start time".
  59.     -- whether the conductor is being driven by an external source such as
  60.         SMPTE.
  61.  
  62. Time Formats
  63. ~~~~~~~~~~~~
  64.     Often times, and application will want to receive timing information
  65. in its own particular format. Particularly, a music program might want to
  66. scale the current clock time based on the current tempo setting, a video
  67. application might want to format the time into SMPTE format, etc. RealTime
  68. provides a way for applications to attach an application-specific
  69. conversion function to their player.
  70.     In addition, there is an added complexity having to do with music
  71. programs. RealTime itself only deals in 600Hz ticks -- it has no
  72. understanding of things such as tempo, accelerando, ritardando, rubato,
  73. etc. It is up to the application to provide these features, by scaling the
  74. incoming clock times based on its current internal variables. The
  75. suggested method for doing this is to use delta-times -- i.e. take the
  76. current conductor time, subtract the previous conductor time, multiply or
  77. divide that by the current tempo scaling factor, and add that to the
  78. musical time counter. Of course, the program must save the remainder and
  79. add it into the calculation for the next time if they want any sort of
  80. long term accuracy (with this method, you can get very long term accuracy
  81. needed for motion picture work).
  82.     A special field has been provided in the PlayerInfo structure for
  83. storing application- specific time, called pi_MetricTime (Issue: May be
  84. changed to pi_ApplicationTime or pi_FormattedTime).
  85.     A second complexity occurs when more than one music application is
  86. playing. Since each application will be using a different algorithm for
  87. computing tempo, it is likely that music applications would soon go out of
  88. sync, even though they are being fed the same clock pulses. For example,
  89. one program might support accelerando (the ability to gradually play
  90. faster and faster), while another might only support immediate changes to
  91. the playback rate.
  92.     In order to resolve this problem, each Conductor contains a way for
  93. musically-aware applications to distribute musical timing information
  94. between themselves, in addition to the non-musical timing information
  95. provided by RealTime. The conductor contains a field called cdt_Metronome,
  96. which is used to store the current musical time (in 480ths of a quarter
  97. note [Issue: I think this is a good number]). For each conductor,
  98. RealTime will attempt to find the first musically-aware application on
  99. its PlayerInfo list. (Note: The application must indicate that it is
  100. musically aware by setting the PLAYER_Conducted tag attribute). The first
  101. application so found is designated as the "Maestro" and gets to set the
  102. musical time for all other musically aware applications. It is the duty of
  103. the Maestro to fill in the cdt_Metronome so that other musically aware
  104. applications can use it.
  105.     Since the PlayerInfo list is kept in order by node priority,
  106. applications which are more sophisticated about tempo should set their
  107. node priority to a higher number so that they can get to be the Maestro,
  108. thus allowing the other applications to take avantage of their superior
  109. features (Optionally, the player priority could be user-settable). Here
  110. are some suggestions for PlayerInfo priorities:
  111.  
  112.     less than zero          -- limited control of tempo (slow, fast, etc).
  113.     0-9                     -- single-rate tempo (no tempo changes)
  114.     10-19                   -- supports instantaneous tempo changes
  115.     20-29                   -- supports accelerando / deccelarando
  116.     30-39                   -- supports rubato, "human" tempos, or special
  117.                                 effects such as playing at half-speed, etc.
  118.  
  119.     Once the cdt_Metronome has been filled in, a special bit,
  120. CONDUCTF_METROSET, will be set indicating that the metronome has been set.
  121. Then other applications can check to see if the bit is set and use the
  122. time -- if the bit is not set, then they must be the Maestro, so they must
  123. set the bit and fill in the cdt_Metronome.
  124.     What this means is that any application that looks at cdt_Metronome,
  125. no matter how simple, must tell RealTime that it is musically aware (using
  126. the PLAYER_Conducted tag), and must take responsibility for the fact that
  127. it may end up being the Maestro.
  128.  
  129. Negative Time
  130. ~~~~~~~~~~~~~
  131.     Note that all time formats are allowed to be negative. There are a
  132. number of cases where a negative time might occur:
  133.     -- A SMPTE reader is hooked up and it contains an "offset" feature,
  134. but the videotape has been rewound to a point before the offset.
  135.     -- A musical application which allows a "count-down" before the music
  136. actually starts.
  137.     However, none of the time formats may go backwards while the clock is
  138. running. They must proceed monotonically forward, if they move at all.
  139.  
  140. Ready Bits
  141. ~~~~~~~~~~
  142.     Each PlayerInfo maintains a "ready bit" which is used to tell RealTime
  143. that the player is ready to receive ticks. This bit is reset each time
  144. that RealTime relocates the clock to a new time. The reason for the ready
  145. bit is that some application need to find the appropriate location in the
  146. score or sequence list before they can start playing. In some modes,
  147. RealTime will wait until all the players are ready before starting the
  148. clock. In other modes RealTime will start the clock immediately, but won't
  149. send any clock pulses to a player that is not ready. Which of these two
  150. cases occurs is up to the application which actually caused the clock to
  151. start, however in practice it usually depends on whether the clock was
  152. started by the user (who can afford to wait a moment), or by an external
  153. timing source (which might not be capable of waiting).
  154.     Players can change the state of their ready bit by using the
  155. PLAYER_Ready tag attribute.
  156.  
  157. Conductor States
  158. ~~~~~~~~~~~~~~~~
  159.     Conductors have basically 4 states:
  160.  
  161.     CLOCKSTATE_STOPPED: The clock is not running.
  162.     CLOCKSTATE_PAUSED: From RealTime's point of view, this is identical to
  163.             being stopped; However, some applications may wish to make a
  164.             distinction between the two states.
  165.     CLOCKSTATE_LOCATING: Tells RealTime to start the clock, but only when
  166.             all players are ready. When all players are ready, RealTime will
  167.             then automatically go into Running mode. Players can change
  168.             their "ready" state using the PLAYER_Ready tag attribute.
  169.     CLOCKSTATE_RUNNING: The clock is started, and time pulses are being
  170.             distributed to any applications are ready. Note that if the
  171.             clock is set to "running" mode directly (without going to
  172.             locate mode) then the applications will have to "catch up" as
  173.             best they can (like a man chasing after a train leaving the
  174.             station). This happens all the time in music applications and
  175.             is normally not a problem -- generally what happens is that the
  176.             applications play silently to themselves (perhaps sending out
  177.             control information to make sure that external devices are in
  178.             the right state when we start playing for real), and then start
  179.             playing for real when they finally catch up.
  180.  
  181.     Any player may change the conductor state at any time by calling:
  182.  
  183.         SetConductorState(playerinfo, newstate, clocktime);
  184.  
  185.     (Clocktime is ignored for stopped and paused states).
  186.  
  187.     There is a special "fifth state" that is not really a state, called
  188. CLOCKSPECIAL_METRIC. When you call SetConductorState() with this state,
  189. what RealTime does is send a message to the Maestro (i.e. the ranking
  190. musically-aware application) asking it to locate in musical time, rather
  191. than in clock ticks. The Maestro will use its internal tempo conversion
  192. routine, tempo map, or whatever application specific method it uses, to
  193. convert the time from metronome units to 600 Hz RealTime clock units. Then
  194. the Maestro should set the clock state to CLOCKSTATE_LOCATE with the newly
  195. computed time.
  196.     What this does is allows any musically-aware application to locate the
  197. clock to a particular measure or note, yet still utilize the superior
  198. timing features of the current Maestro application. For example, you may
  199. want to start playing "at the third measure". RealTime has no concept of
  200. "measures", so it's up to the maestro to tell RealTime what that means in
  201. terms of actual clock time.
  202.     Note that this will probably take slightly longer than a regular
  203. locate, because the Maestro may need to do an internal locate first to do
  204. the time computation.
  205.  
  206. Creating a Conductor
  207. ~~~~~~~~~~~~~~~~~~~~
  208.     Conductors are created automatically whenever any player attempts to
  209. refer to them, and are deleted whenever the number of players referring to
  210. them falls to zero.
  211.  
  212. Creating a Player
  213. ~~~~~~~~~~~~~~~~~
  214.     To create a player, you'll need to call CreatePlayerA(), which takes a
  215. taglist of options that specify the name of the player, the name of the
  216. conductor to attach it to (or create if it doesn't already exist), the
  217. priority of the player in the player list, etc. There are also tag items
  218. to set the player ID and UserData fields, which are available for
  219. application-specific use.
  220.     The PLAYER_ID attribute deserves special attention. This can be used
  221. by applications to distinguish one player from another, which might be
  222. useful in cases where an application has more than one PlayerInfo. For
  223. example, a music sequencer might want a normal player for playing music,
  224. and a special player attached to a "private" conductor (see the autodocs
  225. on how to do this). The private conductor would be used to provide timing
  226. for the program's internal features such as timeouts, feedback notes, and
  227. other things that normally would not be synchronized to other
  228. applications. (Private conductors are basically used for anything that you
  229. would normally want to use an Amiga CIA timer for.)
  230.  
  231.     A player's attributes can be changed later by calling SetPlayerAttrs().
  232. In addition, SetPlayerAttrs is also used for a number of other things, for
  233. example to set the ready bit for the player.
  234.  
  235.     Players are deleted by calling DeletePlayer();
  236.  
  237. Alarms
  238. ~~~~~~
  239.     Each player has an "alarm" which will cause a signal to go off when
  240. the application reaches a specified time. Note that the alarm field is
  241. checked against the pi_MetricTime, not the conductor time, which means
  242. that the alarm can be in the application's own format. (Note that if there
  243. is no player hook, the conductor time will be copied into the
  244. pi_MetricTime field so that alarms still work).
  245.     Alarms are set using the PLAYER_SignalTask, PLAYER_AlarmSigBit,
  246. PLAYER_AlarmTime and PLAYER_AlarmOn tags.
  247.  
  248. Player Hooks
  249. ~~~~~~~~~~~~
  250.     Players can have a callback hook which is invoked at each clock tick,
  251. but only while the clock is running, and only if the player is ready
  252. (there are some other criterion as well, for example if the clock has
  253. somehow advances beyond external sync it will freeze until the external
  254. time source can catch up). The hook is set up using the PLAYER_Hook tag.
  255.     A properly written player hook will have a number of tasks to perform.
  256. First off, there are three possible "messages", or event types, which can
  257. invoke the player hook, and each carries a different data structure and
  258. must be handled differently:
  259.  
  260.     -- clock ticks (indicated by PM_TICK method)
  261.     -- clock state changes (indicated by PM_STATE method)
  262.     -- clock special locate (inidicated by PM_POSITION method)
  263.  
  264.     Here is an overview of how a player hook which supports all possible
  265. features might look:
  266.  
  267.     determine type of message:
  268.  
  269.         case PM_TICK:
  270.  
  271.             get the current tick number from the hook message
  272.  
  273.             if we are a musically-aware application:
  274.  
  275.                 If CONDUCTF_METROSET is set
  276.                     get the time from cdt_Metronome.
  277.                 else
  278.                     convert the tick to musical time (perhaps using
  279.                     delta-time calculations), and place in
  280.                     cdt_Metronome.
  281.  
  282.                     set the CONDUCTF_METROSET flag
  283.                 endif
  284.  
  285.                 convert the cdt_Metronome time, or the current tick number
  286.                 (whichever is preferred by the application) to application-
  287.                 specific format and place in pi_MetricTime.
  288.  
  289.             else
  290.  
  291.                 convert tick number to application-specific format
  292.                 (perhaps using delta-time calculations) and place in
  293.                 pi_MetricTime.
  294.  
  295.             endif
  296.  
  297.         case PM_STATE:
  298.  
  299.             signal application main task that we changed state
  300.  
  301.         case PM_POSITION:
  302.  
  303.             from the hook message, get the musical time to locate to and
  304.                 save in a variable.
  305.             signal main task that a "special locate" has been requested.
  306.  
  307. External Synchronization
  308. ~~~~~~~~~~~~~~~~~~~~~~~~
  309.     Each RealTime conductor has a special external sync input, which can
  310. be used to force the conductor to synchronize with an external timing
  311. source.
  312.     Applications which want to feed external time pulses into a Conductor
  313. must also be a player, so that the conductor will remain in existence.
  314. However, some specialized applications (such a SMPTE reader utility) will
  315. not need all the features of a full PlayerInfo, so a special tag,
  316. PLAYER_Quiet, has been defined which allows for a "placeholder" PlayerInfo
  317. to be created. This inactive player will always be skipped over during
  318. time distribution.
  319.     The second thing required is that the application must inform the
  320. Conductor that it wishes to take over. This is done by setting the
  321. PLAYER_ExtSync attribute using SetPlayerAttrs(). This call is neccessary
  322. because there can only be one external sync source per Conductor, and
  323. RealTime needs to arbitrate these. (Note that the call can fail).
  324.     Finally, the function must call ExternalSync() each time it gets an
  325. external sync call. ExternalSync has three parameters:
  326.     -- the address of the player
  327.     -- the current time (in 600 Hz units)
  328.     -- the estimated time of the next external clock tick.
  329.  
  330.     The reason for the third parameter is to allow the Conductor to
  331. interpolate between external ticks. For example, suppose you have a SMPTE
  332. reader which has external ticks coming in a 30 frames per second. Suppose
  333. that frame #15 has just occured, which corresponds to 300 RealTime clock
  334. ticks. Since each external clock tick (1/30th of a second) corresponds to
  335. 20 RealTime clock ticks, the estimated time of the next external clock
  336. tick is 320.
  337.     What this does is allow the conductor to run at its normal 600 Hz
  338. rate, however the clock values are clamped between the values 300 and 320.
  339. (with the stipulation that the clock can never go backwards if it's
  340. already too far ahead). Thus, the applications get the benefit of 2 ms
  341. timing accuracy, but can still maintain synchronization with the external
  342. source.
  343.  
  344.     Note that since the external sync application as a PlayerInfo, it can
  345. start and stop the clock. This feature is primarily designed for devices
  346. such as SMPTE readers -- the sync driver could have a feature to allow the
  347. clock to be started automatically whenever the sync driver senses the tape
  348. is moving. Thus, all the user has to do is press "play" on the videotape
  349. player, and all of his music and animations start playing along
  350. automatically, and in perfect synchronization.
  351.  
  352.     One other thing to note is that even when the clock is in "running"
  353. state, and all the applications are ready, the Conductor will not
  354. distribute any clock ticks until the first external clock tick is
  355. received. This prevents "false starts" and other inconvenient effects.
  356.  
  357. Credits
  358. ~~~~~~~
  359.     RealTime was envisioned by David Joiner (a.k.a. Talin) and implemented
  360. by Joe Pearce. Bill Barton also made a number of important suggestions.
  361.